/* @(#)GcgMultiShiftController.java
** 
** Copyright (C) 2012 by Steven D. Stamps
**
**             Trademarks & Copyrights
** Flywheel Management Science(TM), Flywheel Management Model(TM),
** Flywheel Story Editor(TM) and FlywheelMS(TM) are exclusive trademarks
** of Steven D. Stamps and may only be used freely for the purpose of
** identifying the unforked version of this software.  Subsequent forks
** may not use these trademarks.  All other rights are reserved.
**
** DecKanGL (Decorated Kanban Glyph Language) and TribKn (Tribal Knowledge)
** are also exclusive trademarks of Steven D. Stamps.  These may be used
** freely within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** gConGUI (game Controller Graphical User Interface) is an exclusive
** trademark of Steven D. Stamps.  This trademark may be used freely
** within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** Trademark information is available at
** <http://www.flywheelms.com/trademarks>
**
** Flywheel Management Science(TM) is a copyrighted body of management
** metaphors, governance processes, and leadership techniques that is
** owned by Steven D. Stamps.  These copyrighted materials may be freely
** used, without alteration, by the community (users and developers)
** surrounding this GPL3-licensed software.  Additional copyright
** information is available at <http://www.flywheelms.org/copyrights>
**
**              GPL3 Software License
** This program is free software: you can use it, redistribute it and/or
** modify it under the terms of the GNU General Public License, version 3,
** as published by the Free Software Foundation. This program is distributed
** in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
** even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
** PURPOSE.  See the GNU General Public License for more details. You should
** have received a copy of the GNU General Public License, in a file named
** COPYING, along with this program.  If you cannot find your copy, see
** <http://www.gnu.org/licenses/gpl-3.0.html>.
*/

package com.flywheelms.library.gcg.widget;

import java.util.ArrayList;

import com.flywheelms.library.gcg.interfaces.GcgMultiShiftControllerParent;
import com.flywheelms.library.gcg.interfaces.GcgMultiShiftStateListener;

public class GcgMultiShiftController {
	
	private final GcgMultiShiftControllerParent multiShiftControllerParent;
	private ArrayList<GcgMultiShiftButton> multiShiftButtonList;
	private GcgMultiShiftButton leftMultiShiftButton;
	private GcgMultiShiftButton rightMultiShiftButton;
	private GcgMultiShiftState dualTouchState = GcgMultiShiftState.OFF;
	private ArrayList<GcgMultiShiftClientButton> buttonListenerList =
			new ArrayList<GcgMultiShiftClientButton>();
	private ArrayList<GcgMultiShiftStateListener> dualTouchStateListenerList =
			new ArrayList<GcgMultiShiftStateListener>();
	private ArrayList<GcgMultiShiftState> enabledMultiShiftStateList;
	
	public GcgMultiShiftController(GcgMultiShiftControllerParent aShiftControllerParent ) {
		this.multiShiftControllerParent = aShiftControllerParent;
		this.multiShiftButtonList = this.multiShiftControllerParent.getShiftButtonList();
		////  START HACK  ////
		/*
		 * in the future, this controller needs to support 2 OR MORE MultiShift buttons  -  SDS
		 */
		this.leftMultiShiftButton = this.multiShiftButtonList.get(0);
		this.rightMultiShiftButton = this.multiShiftButtonList.get(1);
		////  END HACK  ////
		this.enabledMultiShiftStateList = this.multiShiftControllerParent.getSupportedMultiShiftStateList();
	}

	public GcgMultiShiftButton getLeftMultiShiftButton() {
		return this.leftMultiShiftButton;
	}

	public GcgMultiShiftButton getRightMultiShiftButton() {
		return this.rightMultiShiftButton;
	}
	
	public boolean isOff() {
		return this.leftMultiShiftButton.isOff() || this.rightMultiShiftButton.isOff();
	}
	
	public boolean isCtl() {
		return this.leftMultiShiftButton.isCtl() || this.rightMultiShiftButton.isCtl();
	}
	
	public boolean isCtlShift() {
		return this.leftMultiShiftButton.isCtlShift() || this.rightMultiShiftButton.isCtlShift();
	}
	
	public boolean isAlt() {
		return this.leftMultiShiftButton.isAlt() || this.rightMultiShiftButton.isAlt();
	}
	
	public boolean isAltShift() {
		return this.leftMultiShiftButton.isAltShift() || this.rightMultiShiftButton.isAltShift();
	}
	
	public void resetState() {
		this.leftMultiShiftButton.setState(GcgMultiShiftState.OFF.getLevel());
		this.rightMultiShiftButton.setState(GcgMultiShiftState.OFF.getLevel());
		onStateChange(GcgMultiShiftState.OFF);
	}
	
	public GcgMultiShiftState getMultiShiftState() {
		return this.dualTouchState;
	}
	
	public boolean isItemSelectionState() {
		return this.dualTouchState.isItemSelectionState();
	}
	
	private void onStateChange(GcgMultiShiftState aMultiShiftState) {
		for(GcgMultiShiftClientButton aMultiShiftClientButton : this.buttonListenerList) {
			aMultiShiftClientButton.setState(aMultiShiftState);
		}
		for(GcgMultiShiftStateListener aMultiShiftStateListener : this.dualTouchStateListenerList) {
			aMultiShiftStateListener.stateChange(aMultiShiftState);
		}
		this.dualTouchState = aMultiShiftState;
	}

	public void onLeftButtonClick() {
		if(this.leftMultiShiftButton.isCancel()) {
			resetState();
		} else if(this.leftMultiShiftButton.isOff()) {
					this.leftMultiShiftButton.setState(GcgMultiShiftState.CTL.getLevel());
					this.rightMultiShiftButton.setState(GcgMultiShiftState.CANCEL.getLevel());
					onStateChange(GcgMultiShiftState.CTL);
		} else {
			onStateChange(
					this.leftMultiShiftButton.incrementMultiShiftState(this.enabledMultiShiftStateList,
					this.multiShiftControllerParent.isMultipleSelections() ) );
		}
	}
	
	public void onRightButtonClick() {
		if(this.rightMultiShiftButton.isCancel()) {
			resetState();
		} else if(this.rightMultiShiftButton.isOff()) {
					this.rightMultiShiftButton.setState(GcgMultiShiftState.CTL.getLevel());
					this.leftMultiShiftButton.setState(GcgMultiShiftState.CANCEL.getLevel());
					onStateChange(GcgMultiShiftState.CTL);
		} else {
			onStateChange(this.rightMultiShiftButton.incrementMultiShiftState(this.enabledMultiShiftStateList,
					this.multiShiftControllerParent.isMultipleSelections() ) );
		}
	}

	public void addButtonListener(GcgMultiShiftClientButton aMultiShiftClientButton) {
		this.buttonListenerList.add(aMultiShiftClientButton);
	}
	
	public void addMultiShiftStateListener(GcgMultiShiftStateListener aMultiShiftStateListener) {
		this.dualTouchStateListenerList.add(aMultiShiftStateListener);
	}

	private boolean enabledMultiShiftState(GcgMultiShiftState aMultiShiftState) {
		return this.enabledMultiShiftStateList.contains(aMultiShiftState);
	}

}
